import React, { cloneElement, PropsWithChildren, createContext, useState, useMemo } from 'react';


export function RcClass (props: PropsWithChildren<{ className?: string | string[]; cls: { [key: string]: boolean } }>) {
  let names = props.className ? (Array.isArray(props.className) ? props.className : [props.className]) : [];
  for (let key in props.cls) {
    if (typeof key === 'string' && key !== '' && props.cls[key]) {
      names.push(key);
    }
  }
  if (props.children) {
    // @ts-ignore
    let child = cloneElement(props.children, { className: names.join(' ') });
    return <>{child}</>;
  }
  return <>{props.children}</>;
}

const { Provider, Consumer } = createContext<{ zCase: any; matched: boolean; changeMatched:(id: string, isMatch: boolean) => void }>({ zCase: null, matched: true, changeMatched: () => {} });

export function RcSwitch (props: PropsWithChildren<{ value: any }>) {
  const [isMatchCase, setIsMatchCase] = useState<{ [key: string]: boolean }>({});
  const isMatched = useMemo(() => {
    for (let key in isMatchCase) {
      if (isMatchCase[key] === true) {
        return true;
      }
    }
    return false;
  }, [isMatchCase]);
  return (
    <Provider
      value={{
        zCase: props.value,
        matched: isMatched,
        changeMatched: (id: string, isMatch: boolean) => {
          isMatchCase[id] !== isMatch && setIsMatchCase({ ...isMatchCase, [id]: isMatch });
        },
      }}>
      {props.children}
    </Provider>
  );
}

export function RcCase (props: PropsWithChildren<{ value: any; id?: string }>) {
  return (
      <Consumer>
        {value => {
          if (typeof props.value === 'function') {
            if (props.value(value.zCase)) {
              props.id && value.changeMatched(props.id, true);
              return props.children;
            } else {
              props.id && value.changeMatched(props.id, false);
              return <></>;
            }
          } else {
            if (value.zCase === props.value) {
              props.id && value.changeMatched(props.id, true);
              return props.children;
            } else {
              props.id && value.changeMatched(props.id, false);
              return <></>;
            }
          }
        }}
      </Consumer>
  );
}

export function RcDefault (props: PropsWithChildren<{}>) {
  return (
    <Consumer>
      {value => {
        if (value.matched === false) {
          return props.children;
        } else {
          return <></>;
        }
      }}
    </Consumer>
  );
}

export function RcIf (props: PropsWithChildren<{ value: any; else?: any }>) {
  if (props.value) {
    return <>{props.children}</>;
  }
  return props.else ? props.else : <></>;
}
